package com.ruicar.afs.cloud.apply.pre.loan.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.apply.business.service.ApplyAdminService;
import com.ruicar.afs.cloud.apply.common.entity.ApplyCustBaseInfo;
import com.ruicar.afs.cloud.apply.common.entity.PreApproveInfo;
import com.ruicar.afs.cloud.apply.pre.approve.service.PreApproveService;
import com.ruicar.afs.cloud.apply.pre.loan.condition.ApplyAppFaceCondition;
import com.ruicar.afs.cloud.apply.pre.loan.condition.FaceRecognitionLoginCondition;
import com.ruicar.afs.cloud.apply.pre.loan.service.ApplyAppService;
import com.ruicar.afs.cloud.apply.pre.loan.service.ApplyCustBaseInfoService;
import com.ruicar.afs.cloud.apply.pre.smallprogram.condition.TencentCloudNuclearBodyCondition;
import com.ruicar.afs.cloud.bizcommon.face.service.FaceRecognitionService;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.holder.TransRequestContextHolder;
import com.ruicar.afs.cloud.common.core.security.feign.Oauth2OperationService;
import com.ruicar.afs.cloud.common.core.security.service.AfsNoPassLoginService;
import com.ruicar.afs.cloud.common.core.security.service.AfsUser;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.core.util.Base64Util;
import com.ruicar.afs.cloud.common.core.util.ClientTypeUtil;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.image.entity.ComAttachmentFile;
import com.ruicar.afs.cloud.image.entity.ComAttachmentManagement;
import com.ruicar.afs.cloud.image.service.ComAttaManageService;
import com.ruicar.afs.cloud.image.service.ComAttachmentFileService;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.ruicar.afs.cloud.apply.common.utils.ApplyConstants.*;

/**
 * @description: 人脸识别
 * @author: mingzhi.li
 * @date: 2020/8/7 14:28
 */
@Slf4j
@RestController
@RequestMapping("/applyAppFace")
@AllArgsConstructor
public class ApplyAppFaceController {

    private FaceRecognitionService faceRecognitionService;
    private final ComAttachmentFileService attachmentFileService;
    private final Oauth2OperationService oauth2OperationService;
    private final AfsNoPassLoginService afsNoPassLoginService;
    private final ApplyAppService applyAppService;
    private final ComAttaManageService comAttaManageService;
    private final ApplyCustBaseInfoService applyCustBaseInfoService;
    private final PreApproveService preApproveService;
    private final ApplyAdminService applyAdminService;

    @RequestMapping(value = "/getApplyAppFace", method = RequestMethod.POST)
    @ApiOperation(value = "人脸识别")
    public IResponse getApplyAppFace(@RequestBody ApplyAppFaceCondition condition) {
        if(StrUtil.isBlank(condition.getApplyNo())){
            return IResponse.fail("申请编号不能为空");
        }
        if(StrUtil.isBlank(condition.getQueryImagePackage())){
            return IResponse.fail("大礼包不能为空");
        }
        if(condition.getCustId() ==null){
            return IResponse.fail("客户id不能为空");
        }
        JSONObject json = new JSONObject();
        IResponse iResponse = applyAppService.signToFace(condition);
        if(CODE_SUCCESS.equals(iResponse.getCode())){
            json = (JSONObject) iResponse.getData();
        }else{
            return IResponse.fail(iResponse.getMsg());
        }
        ApplyCustBaseInfo info = applyCustBaseInfoService.getOne(Wrappers.<ApplyCustBaseInfo>query().lambda()
                .eq(ApplyCustBaseInfo::getId, condition.getCustId()));
        JSONObject result = faceRecognitionService.FaceRecognitionCheck(json);
        if(result !=null){
            JSONObject object = new  JSONObject();
            if(ST_SUCCESS_CODE.equals(result.getString("code"))){
                JSONObject resultObject = result.getJSONObject("result");
                if(ST_SUCCESS.equals(resultObject.getString("code"))){
                    object.put("code",resultObject.getString("code"));
                    object.put("message",resultObject.getString("message"));
                    object.put("pairVerifySimilarity",resultObject.getString("pairVerifySimilarity"));
                    String photo =  resultObject.getString("photo");
                    if(info !=null){
                        info.setSignFailNumber(0);
                        //更新错误次数为0
                        applyCustBaseInfoService.updateById(info);
                        //上传面签照片
                        applyAppService.faceToFaceSign(info,photo,condition);
                    }
                    return IResponse.success(object);
                }else{
                    JSONObject fileObject = result.getJSONObject("result");
                    String photo =  fileObject.getString("photo");
                    if(photo !=null){
                        if(info !=null){
                            //人脸对比失败，计入失败次数
                            log.info("人脸核对未通过结果"+resultObject);
                            int signFailNumber =  info.getSignFailNumber() == null ? 0 : info.getSignFailNumber();
                            info.setSignFailNumber(signFailNumber+1);
                            applyCustBaseInfoService.updateById(info);
                            applyAppService.faceToFaceSign(info,photo,condition);
                        }
                    }
                    return IResponse.fail("人脸核对未通过");
                }
            }else{
                return IResponse.fail("人脸核对未通过");
            }
        }else{
            log.info("思图比对结果为null");
            return IResponse.fail("人脸核对失败!");
        }
    }

    @RequestMapping(value = "/faceRecognitionLogin", method = RequestMethod.POST)
    @ApiOperation(value = "人脸识别登陆")
    public IResponse faceRecognitionLogin(@RequestBody FaceRecognitionLoginCondition condition) {
        if(StrUtil.isBlank(condition.getUserName())){
            return IResponse.fail("登陆账号不能为空");
        }
        if(StrUtil.isBlank(condition.getQueryImagePackage())){
            return IResponse.fail("大礼包不能为空");
        }

        //构建 http请求参数
        Map<String, String> requestParam = new HashMap<>(8);
        requestParam.put(CommonConstants.GRANT_TYPE, "password");
        //用户名为前缀+系统登录名
        requestParam.put(CommonConstants.USERNAME, CommonConstants.WITH_OUT_PASS_PREFIX+condition.getUserName());
        //密码填系统默认密码
        requestParam.put(CommonConstants.PASSWORD, CommonConstants.DEFAULT_PASS);
        requestParam.put(CommonConstants.TENANT_ID, CommonConstants.BASE_TENANT_ID);
        //填充一次性校验码，使用过后不能再次使用,校验码有效期为 120s
        requestParam.put(CommonConstants.NO_PASS_LOGIN,afsNoPassLoginService.getCheckCode());
        //构建 http请求头
        Map<String, String> requestHeader = new HashMap<>(8);
        ClientTypeUtil.ClientTypeEnum clientTypeEnum = TransRequestContextHolder.getClientInfo().getClientType();
        requestHeader.put(CommonConstants.AUTHORIZATION, "Basic " + Base64Util.encode((clientTypeEnum.getClientId()+ ":" + clientTypeEnum.getClientSecret()).getBytes()));
        Map map = (Map) oauth2OperationService.login(requestParam,requestHeader);
        if(map ==null){
            return IResponse.fail("用户信息不存在");
        }
        //根据登陆账号，拿到用户对应小类标识
        String user_id= (String) map.get("user_id");
        JSONObject json = new JSONObject();
        IResponse comAttach = applyAdminService.getUserFileByUserId(user_id);
        if(CODE_SUCCESS.equals(comAttach.getCode())){
            Map mapAttach = (Map) comAttach.getData();
            ComAttachmentFile attachmentFile = new ComAttachmentFile();
            attachmentFile.setFileId((String) mapAttach.get("fileId"));
            attachmentFile.setFileName((String) mapAttach.get("fileName"));
            byte[] fileByte = attachmentFileService.downloadAttachmentFile(attachmentFile);
            try {
                if (fileByte.length > 0) {
                    String databaseImageContent = Base64.encodeBase64String(fileByte);
                    //被对比图片
                    json.put("databaseImageContent", databaseImageContent);
                }
            } catch (Exception e) {
                log.error("文件下载失败:" + e.getMessage());
            }
        }else{
            return IResponse.fail("见证人脸对比图片不能为空或管理员账号无法登陆");
        }
        json.put("queryImagePackage", condition.getQueryImagePackage());
        json.put("databaseImageType","1");
        JSONObject result = faceRecognitionService.FaceRecognitionCheck(json);
        if(result !=null){
            JSONObject object = new  JSONObject();
            if(ST_SUCCESS_CODE.equals(result.getString("code"))){
                JSONObject resultObject = result.getJSONObject("result");
                if(ST_SUCCESS.equals(resultObject.getString("code"))){
                    object.put("code",resultObject.getString("code"));
                    object.put("message",resultObject.getString("message"));
                    object.put("pairVerifySimilarity",resultObject.getString("pairVerifySimilarity"));
                    return IResponse.decode(map);
                }else{
                    log.info("人脸核对未通过结果"+resultObject);
                    return IResponse.fail("人脸核对未通过");
                }
            }else{
                log.info("人脸核对未通过结果"+result);
                return IResponse.fail("人脸核对未通过");
            }
        }else{
            log.info("思图比对结果"+result);
            return IResponse.fail("人脸核对失败!");
        }

    }

    @RequestMapping(value = "/getTrialBatchInfoFace", method = RequestMethod.POST)
    @ApiOperation(value = "预审批人脸识别")
    public IResponse getTrialBatchInfoFace(@RequestBody ApplyAppFaceCondition condition) {

        if(StrUtil.isBlank(condition.getQueryImagePackage())){
            return IResponse.fail("大礼包不能为空");
        }
        if(condition.getCustId() ==null){
            return IResponse.fail("客户id不能为空");
        }
        //根据客户id判断角色，拿到角色对应小类标识记录
        ComAttachmentManagement comAttachmentManagement =comAttaManageService.getOne(Wrappers.<ComAttachmentManagement>query().lambda()
                .eq(ComAttachmentManagement::getUniqueCode, PRE_BORROWER_ID_CARD_FRONT));
        if(comAttachmentManagement ==null){
            return IResponse.fail("预审客户附件表识不存在");
        }
        List<ComAttachmentFile> comAttachmentFileList = attachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                .eq(ComAttachmentFile::getBusiNo, condition.getCustId())
                .eq(ComAttachmentFile::getAttachmentCode,comAttachmentManagement.getId().toString()).orderByDesc(ComAttachmentFile::getCreateTime));
        JSONObject json = new JSONObject();
        if(comAttachmentFileList !=null && comAttachmentFileList.size()>0){
            ComAttachmentFile file = comAttachmentFileList.get(0);
            ComAttachmentFile attachmentFile = attachmentFileService.getById(file.getId());
            if(attachmentFile== null){
                return IResponse.fail("文件id不存在");
            }
            byte[] fileByte = attachmentFileService.downloadAttachmentFile(attachmentFile);
            try {
                if (fileByte.length > 0) {
                    String databaseImageContent = Base64.encodeBase64String(fileByte);
                    //被对比图片
                    json.put("databaseImageContent", databaseImageContent);
                }
            } catch (Exception e) {
                log.error("文件下载失败:" + e.getMessage());
            }
        }else{
            return IResponse.fail("人脸对比图片不能为空");
        }
        json.put("queryImagePackage", condition.getQueryImagePackage());
        json.put("databaseImageType","1");
        JSONObject result = faceRecognitionService.FaceRecognitionCheck(json);
        PreApproveInfo info = preApproveService.getOne(Wrappers.<PreApproveInfo>query().lambda()
                .eq(PreApproveInfo::getId, condition.getCustId().toString()));
        if(info ==null){
            return IResponse.fail("预审客户信息不存在");
        }
        log.info("获取客户预审批信息");
        if(result !=null){
            JSONObject object = new  JSONObject();
            if(ST_SUCCESS_CODE.equals(result.getString("code"))){
                JSONObject resultObject = result.getJSONObject("result");
                if(ST_SUCCESS.equals(resultObject.getString("code"))){
                    object.put("code",resultObject.getString("code"));
                    object.put("message",resultObject.getString("message"));
                    object.put("pairVerifySimilarity",resultObject.getString("pairVerifySimilarity"));
                    info.setSignFailNumber(0);
                    preApproveService.updateById(info);
                    return IResponse.success(object);
                }else{
                    int signFailNumber =  info.getSignFailNumber() == null ? 0 : info.getSignFailNumber();
                    info.setSignFailNumber(signFailNumber+1);
                    preApproveService.updateById(info);
                    log.info("人脸核对未通过结果"+resultObject);
                    return IResponse.fail("人脸核对未通过");
                }
            }else{
                log.info("人脸核对未通过结果"+result);
                return IResponse.fail("人脸核对未通过");
            }
        }else{
            log.info("思图比对结果为null");
            return IResponse.fail("人脸核对失败!");
        }
    }

    /**
     * 获取人脸识别错误次数
     *
     * @return
     */
    @PostMapping("/getApplySignNumber")
    @ApiOperation(value = "获取人脸识别错误次数")
    public IResponse getApplySignNumber(@RequestBody TencentCloudNuclearBodyCondition condition) {
        if(StrUtil.isBlank(condition.getSignScene())){
            return IResponse.fail("签约场景不能为空！");
        }
        if(MESSAGE_TYPE_ZERO.equals(condition.getSignScene())){
            if(condition.getPreId()==null){
                return IResponse.fail("预审客户id不能为空！");
            }
            PreApproveInfo info = preApproveService.getOne(Wrappers.<PreApproveInfo>query().lambda()
                    .eq(PreApproveInfo::getId, condition.getPreId()));
            if(info ==null){
                return IResponse.fail("预审客户信息不存在");
            }
            if(info.getSignFailNumber() ==null){
                info.setSignFailNumber(0);
            }
            return IResponse.success(info.getSignFailNumber());
        }else{
            if(condition.getCustId()==null){
                return IResponse.fail("客户id不能为空！");
            }
            ApplyCustBaseInfo info = applyCustBaseInfoService.getOne(Wrappers.<ApplyCustBaseInfo>query().lambda()
                    .eq(ApplyCustBaseInfo::getId, condition.getCustId()));
            if(info ==null){
                return IResponse.fail("客户信息不存在！");
            }
            if(info.getSignFailNumber() ==null){
                info.setSignFailNumber(0);
            }
            return IResponse.success(info.getSignFailNumber());
        }
    }
}
